<?php
/**
 * Created by 惠达浪
 * Email: crazys@126.com
 * Date: 2018/11/20
 * Time: 11:18
 */

namespace app\api\controller;

use app\api\facade\TokenService;
use app\lib\enum\ErrorCodeEnum;
use think\Container;
use think\exception\HttpResponseException;
use think\facade\Config;
use think\facade\Response;
use think\model\Collection;
use think\Request;

/**
 * 控制器基类
 *
 * @package app\api\controller
 */
class BaseController {
    /**
     * 用户token
     *
     * @var string
     */
    protected $token;
    /**
     * Request实例
     *
     * @var \think\Request
     */
    protected $request;

    /**
     * 构造函数
     *
     * @param Request|null $request
     */
    public function __construct(Request $request = null) {
        $this->request = is_null($request) ? Container::get('request') : $request;
        $this->token = $this->request->server('HTTP_AUTHORIZATION') ?: '';

    }

    /**
     * 空方法操作，防止其它异常抛出
     */
    public function _empty() {
        $this->jsonReturn(ErrorCodeEnum::UNKNOWN_ERROR, '访问的页面不存在', null, [], 404);
    }

    /**
     * 向客户端返回数据
     * 该方法旨在简化数据判断等操作
     *
     * @param object/array $data 返回的数据
     *
     * @return \think\response
     */
    protected function returnData($data) {
        $type = Config::get('default_return_type');

        if ($data instanceof Collection) {
            $isEmpty = $data->isEmpty();
        } else {
            $isEmpty = empty($data);
        }

        if ($isEmpty) {
            $returnData = Response::create([
                'errorCode' => ErrorCodeEnum::EMPTY_DATA,
                'msg' => '没有找到数据'
            ], 'json');
        } else {
            $returnData = Response::create($data, $type);
        }
        return $returnData;
    }

    /**
     * 成功时返回
     *
     * @param string $msg    提示信息
     * @param array  $data   携带的数据
     * @param array  $header http文件的Header信息
     */
    protected function success($msg, $data = [], array $header = []) {
        $this->jsonReturn(0, $msg, $data, $header);
    }

    /**
     * 失败时返回
     *
     * @param string $msg      提示信息
     * @param int    $code     错误码，默认为-1
     * @param array  $data     携带的数据
     * @param array  $header   http文件的Header信息
     * @param int    $httpCode http状态码
     */
    protected function error($msg, $code = -1, $data = [], array $header = [], $httpCode = 200) {
        $this->jsonReturn($code, $msg, $data, $header, $httpCode);
    }

    /**
     * 操作跳转的快捷方法
     *
     * @access protected
     *
     * @param int    $code     判断成功与否的状态码,0失败，1成功
     * @param string $msg      提示信息
     * @param array  $data     返回的数据
     * @param array  $header   发送的Header信息
     * @param int    $httpCode http状态码，默认为200
     *
     * @return void
     */
    private function jsonReturn($code, $msg, $data, array $header = [], $httpCode = 200) {
        $result = [
            'errorCode' => $code,
            'msg' => $msg
        ];

        empty($data) or $result['data'] = $data;

        $response = Response::create($result, 'json', $httpCode, $header);
        throw new HttpResponseException($response);
    }

    /**
     * 校验令牌是否合法，通常用以检查是否登录
     */
    protected function checkToken() {
        if (empty($this->token)) {
            $this->error('尚未登录！', ErrorCodeEnum::LOGIN_FALLED, [], [], 401);
        }
        if (!TokenService::verifyToken($this->token)) {
            $this->error('令牌失效！', ErrorCodeEnum::TOKEN_INVALID, [], [], 403);
        }
    }
}